package com.wdh.monitor.aop;

import com.wdh.monitor.annotation.Monitor;
import com.wdh.monitor.base.MonitorProducer;
import com.wdh.monitor.dto.MonitorDto;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class MonitorAop {

    private static final ThreadLocal<MonitorDto> monitorHolder = new ThreadLocal<>();

    @Autowired
    private MonitorProducer monitorProducer;

    @Pointcut("@annotation( com.wdh.monitor.annotation.Monitor)")
    public void cutPoint(){
    }

    @Before("cutPoint()")
    public void cutProcess(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取目标类上的目标注解（可判断目标类是否存在该注解）
       // Monitor annotationInClass = AnnotationUtils.findAnnotation(signature.getClass(), Monitor.class);
        Monitor annotation = AnnotationUtils.findAnnotation(signature.getMethod(), Monitor.class);
        String value = annotation.value();

        MonitorDto dto = new MonitorDto();
        dto.setMonitorName(value);
        dto.setStartTime(System.currentTimeMillis());
        monitorHolder.set(dto);
    }

    @After("cutPoint()")
    public void after(JoinPoint joinPoint) {
        MonitorDto dto = monitorHolder.get();
        dto.setEndTime(System.currentTimeMillis());
        dto.setExp(false);
        monitorHolder.remove();
        monitorProducer.sendMq(dto);
    }




    @AfterThrowing(value = "cutPoint()", throwing = "e")
    public void afterThrow(JoinPoint joinPoint, Exception e) {
        MonitorDto dto = monitorHolder.get();
        dto.setEndTime(System.currentTimeMillis());
        dto.setExp(true);
        monitorHolder.remove();
        monitorProducer.sendMq(dto);
    }

}
